package cn.zero.flowspringbootstater.api;


import cn.zero.flowspringbootstater.modular.bean.FlowErrorException;
import cn.zero.flowspringbootstater.modular.bean.Result;
import cn.zero.flowspringbootstater.modular.entity.Flow;
import cn.zero.flowspringbootstater.modular.vo.*;
import cn.zero.flowspringbootstater.service.IFlowService;
import cn.zero.flowspringbootstater.service.impl.FlowServiceImpl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 *
 * 审批流程
 *
 *
 * @author lei
 * @since 2022-06-17
 */
@Slf4j
@RestController
@Validated
@RequestMapping("/system/v1/flow")
public class FlowController {

    private final FlowServiceImpl flowService;

    @Autowired
    public FlowController(FlowServiceImpl flowService){
        this.flowService = flowService;
    }

    /**
     * 新增/编辑/删除审批流程
     * @since 标记
     * @param flowParamVo:
     * @return: cn.ygkj.logistics.common.core.utils.Result
     * @author: lei
     */
    @PostMapping("/edit")
    public Result<Long> addFlow(@RequestBody FlowParamVo flowParamVo) {
        return filterError(() -> Result.success(flowService.editFlow(flowParamVo)));

    }

    /**
     * 通用审批接口
     * @param params:
     * @return: cn.ygkj.system.api.dto.FlowApprovalRes
     * @author: lei
     */
    @PostMapping("/approval")
    public Result<FlowApprovalRes> approval(@RequestBody @Validated FlowApprovalDto params){
        return filterError(() -> Result.success(flowService.approval(params)));

    }
    /**
     * 绑定审批流程
     * @param params:
     * @return: cn.ygkj.system.api.dto.FlowBindRes
     * @author: lei
     */
    @PostMapping("/bindFlow")
    public Result<FlowBindRes> bindFlow(@RequestBody@Validated FlowBindDto params){
        return filterError(() -> Result.success(flowService.bindFlow(params)));
    }


    /**
     * 查看业务数据当前的审批状态
     *
     * @param flowId     流程id
     * @param businessId 业务id
     * @return: cn.ygkj.logistics.common.core.utils.Result
     * @author: lei
     */
    @GetMapping("/getCurrentFlowState")
    public Result<FlowBusinessVo> getFlowNodeDetail(@NotBlank(message = "流程id不能为空") String flowId, @NotBlank(message = "业务d不能为空") String businessId) {
        return filterError(() -> Result.success(flowService.getFlowNodeDetail(flowId, businessId)));
    }

    /**
     * 获取当前可用的流程列表
     * @param flowName 流程名称
     * @param flowCode 流程编号
     * @param type 流程类型
     * @return: cn.ygkj.logistics.common.core.utils.Result
     * @author: lei
     */

    @GetMapping("/getFlowList")
    public Result<Page<Flow>> getFlowList(String flowName, String flowCode, String type,
                                          @RequestParam(value = "pageSize",defaultValue = "10",required = false) Integer pageSize,
                                          @RequestParam(value = "pageNum",defaultValue = "1",required = false) Integer pageNum) {
        Flow flow = new Flow();
        flow.setFlowName(flowName);
        flow.setFlowCode(flowCode);
        flow.setType(type);
        return filterError(() -> Result.success(flowService.selectFlowList(flow,pageSize,pageNum)));
    }

    /**
     * 重置业务的审批流程
     * @param businessId
     * @param flowId
     * @return cn.ygkj.common.core.model.Result
     * @author lei
     */
    @GetMapping("/resetFlow")
    public Result resetFlow(@NotBlank(message = "业务id不能为空") String businessId,@NotNull(message = "流程id不能为空")Long flowId){
        return filterError(() -> Result.success(flowService.resetFlow(businessId, flowId)));

    }

    /**
     * 获取流程配置详情
     * @param id 流程id
     * @return: cn.ygkj.logistics.common.core.utils.Result
     * @author: lei
     */

    @GetMapping("/getFlowDetail")
    public Result<List<FlowParamVo>> getFlowDetail(@NotNull(message = "id不能为空") @RequestParam(value = "id",required = true)  Long id){
        return filterError(() -> Result.success(flowService.getFlowDetail(id)));

    }


    /**
     * 通过业务id查询当前节点的审核权限用户id
     * @param businessIds 业务id
     * @return java.util.List<java.lang.Long>
     * @author lei
     */

    @GetMapping("/getHasRoleUserIdByBusinessId")
    public Result<List<FlowNode2UserVo>> getHasRoleUserIdByBusinessId(@RequestParam("businessIds") Set<String> businessIds){
        return filterError(() -> {
            List<FlowNode2UserVo> res = flowService.getHasRoleUserIdByBusinessId(businessIds)
                    .stream()
                    .filter(f -> StringUtils.isNotBlank(f.getBusinessId())).collect(Collectors.toList());
            return Result.success(res);
        });

    }


    /**
     * 回滚至此业务的上一步，若从已经审批的中间开始回滚，将回滚至{ nodeId }的上一步
     * @param businesId 业务id
     * @param nodeId 当前的节点id
     * @return cn.ygkj.common.core.model.Result<java.lang.Boolean>
     * @author lei
     */
    @GetMapping("/rollbackPrevious")
    public Result<Boolean> rollbackPrevious(String businesId,Long flowId,Long nodeId){
        return filterError(() -> Result.success(flowService.rollbackPrevious(businesId, flowId, nodeId)));

    }


    public static Result filterError(Supplier<Result> f)
    {
        try {
            return f.get();
        } catch (FlowErrorException e)
        {
            return Result.error(e.getMessage());
        }catch (Exception e) {
            log.error("操作发生异常，异常信息{}", e.getMessage());
            return Result.error("服务器繁忙，请稍后再试");
        }

    }
}
